#pragma once
#include <cstdint>
#include <cstring>
#include <memory>
#include <string>
#include "XnccType.h"

namespace xncc {
namespace sys {
    class EventFd;
}  // namespace sys
namespace msg {
    struct MsgHeaderInThread
    {
        uint32_t               len;
        types::message_id_t    id;
        types::connection_id_t connId;
        types::thread_id_t     tid;
    };
    class FIFOQueueElement;
    class FIFOQueue
    {
      public:
        using s_ptr = std::shared_ptr<FIFOQueue>;
        explicit FIFOQueue(types::queue_size_t size, bool autoExpand = false);
        ~FIFOQueue() = default;

        char* getWriteBuffer(types::queue_size_t len);
        char* tryGetWriteBuffer(types::queue_size_t len);
        void  finishWrite();
        void  finishWriteNotNotify();
        char* getReadBuffer(types::queue_size_t len);
        void  finishRead();
        void  setNeedNotify();

        [[nodiscard]] std::string dump() const;

        [[nodiscard]] types::queue_id_t id() const { return queueId_; }

        [[nodiscard]] std::shared_ptr<xncc::sys::EventFd> notifyId() const { return notifyfd_; }

        // private:
        //   void updateCurrentReadPtr();
        //   void updateCurrentWritePtr();

      private:
        bool                                autoExpand_;
        std::shared_ptr<xncc::sys::EventFd> notifyfd_ = nullptr;
        FIFOQueueElement*                   readPtr_;
        FIFOQueueElement*                   writePtr_;
        FIFOQueueElement*                   delList_ = nullptr;
        int                                 lastReadIndex_;
        bool                                isNeedNotify_;
        types::queue_id_t                   queueId_;
    };
}  // namespace msg
}  // namespace xncc
